package com.lb.activity.service.impl;

import com.fasterxml.jackson.databind.util.BeanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lb.activity.service.VacationService;
import com.lb.activity.util.ActivitiUtil;
import com.lb.activity.util.ResultUtil;
import com.lb.activity.vo.User;
import com.lb.activity.vo.VacTask;
import com.lb.activity.vo.Vacation;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author 001030
 */
@Service
public class VacationServiceImpl implements VacationService {

    @Resource
    private RuntimeService runtimeService;
    @Resource
    private IdentityService identityService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;


    private static final String PROCESS_DEFINE_KEY = "vacationProcess";

    /**
     * 开始流程
     * @param request
     * @param vacation
     */
    @Override
    public void startVacation(HttpServletRequest request, Vacation vacation) {
        User user = (User) request.getSession().getAttribute("user");
        identityService.setAuthenticatedUserId(user.getId()+"");
        //开始流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROCESS_DEFINE_KEY);
        //查询当前的任务
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
        //声明任务
        taskService.claim(task.getId(),user.getId()+"");
        Map<String, Object> vars = new HashMap<>(4);
        vars.put("applyUser", user.getId()+"");
        vars.put("days", vacation.getDays());
        vars.put("reason", vacation.getReason());
        taskService.complete(task.getId(), vars);
    }

    /**
     * 查看我的流程
     * @param request
     * @return
     */
    @Override
    public Object myVacation(HttpServletRequest request,Integer page,Integer limit) {
        //PageHelper.startPage(page,limit);
        User user = (User) request.getSession().getAttribute("user");
        List<ProcessInstance> instanceList = runtimeService.createProcessInstanceQuery().startedBy(user.getId()+"").list();
        List<Vacation> vacList = new ArrayList<>();
        for (ProcessInstance instance : instanceList) {
            Vacation vac = getVac(instance);
            vacList.add(vac);
        }
        PageInfo<Vacation> pageInfo = new PageInfo(vacList);
        return ResultUtil.build(0,"",Integer.parseInt(pageInfo.getTotal()+""),vacList);
    }

    /**
     * 我请过的假
     * @param request
     * @return
     */
    @Override
    public Object myHistoryVacation(HttpServletRequest request,Integer page,Integer limit) {
        //PageHelper.startPage(page,limit);
        User user = (User) request.getSession().getAttribute("user");
        List<HistoricProcessInstance> hisProInstance = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(PROCESS_DEFINE_KEY).startedBy(user.getId()+"").finished()
                .orderByProcessInstanceEndTime().desc().list();

        List<Vacation> vacList = new ArrayList<>();
        for (HistoricProcessInstance hisInstance : hisProInstance) {
            Vacation vacation = new Vacation();
            vacation.setApplyUser(hisInstance.getStartUserId());
            vacation.setApplyTime(hisInstance.getStartTime());
            vacation.setApplyStatus("申请结束");
            List<HistoricVariableInstance> varInstanceList = historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(hisInstance.getId()).list();
            ActivitiUtil.setVars(vacation, varInstanceList);
            vacList.add(vacation);
        }
        PageInfo<Vacation> pageInfo = new PageInfo(vacList);
        return ResultUtil.build(0,"",Integer.parseInt(pageInfo.getTotal()+""),vacList);
    }

    /**
     * 我的审批
     * @param request
     * @return
     */
    @Override
    public Object myApproveVacation(HttpServletRequest request,Integer page,Integer limit) {
        //PageHelper.startPage(page,limit);
        User user = (User) request.getSession().getAttribute("user");
        List<Task> taskList = taskService.createTaskQuery().taskCandidateUser(user.getId()+"").orderByTaskCreateTime().desc().list();
        List<VacTask> vacTaskList = new ArrayList<>();
        for (Task task : taskList) {
            VacTask vacTask = new VacTask();
            String instanceId = task.getProcessInstanceId();
            ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
            Vacation vac = getVac(instance);
            BeanUtils.copyProperties(vac,vacTask);
            vacTask.setId(task.getId());
            vacTask.setName(task.getName());
            vacTask.setCreateTime(task.getCreateTime());
                vacTaskList.add(vacTask);
        }
        PageInfo<Vacation> pageInfo = new PageInfo(vacTaskList);
        return ResultUtil.build(0,"",Integer.parseInt(pageInfo.getTotal()+""),vacTaskList);
    }

    /**
     * 查询单个任务
     * @param taskId
     * @param request
     * @return
     */
    @Override
    public VacTask viewVacation(String taskId,HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute("user");
        List<Task> list = taskService.createTaskQuery().taskCandidateUser(user.getId() + "").taskId(taskId).list();
        if(list.size() == 0){
            return null;
        }
        Vacation vac = getVac(runtimeService.createProcessInstanceQuery().processInstanceId(list.get(0).getProcessInstanceId()).singleResult());

        VacTask vacTask = new VacTask();
        BeanUtils.copyProperties(vac,vacTask);
        vacTask.setId(taskId);
        return vacTask;
    }

    /**
     * 回绝任务 或者 通过任务
     * @param vacTask
     * @param request
     * @return
     */
    @Override
    public Object passVacation(VacTask vacTask, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute("user");
        String taskId = vacTask.getId();
        String result = vacTask.getResult();
        Map<String, Object> vars = new HashMap<>();
        vars.put("result", result);
        vars.put("auditor", user.getUserName());
        vars.put("auditTime", new Date());
        taskService.claim(taskId, user.getId()+"");
        taskService.complete(taskId, vars);
        return ResultUtil.ok("操作成功");
    }

    /**
     * 取出任务明细
     * @param instance
     * @return
     */
    private Vacation getVac(ProcessInstance instance) {
        Integer days = runtimeService.getVariable(instance.getId(), "days", Integer.class);
        String reason = runtimeService.getVariable(instance.getId(), "reason", String.class);
        Vacation vac = new Vacation();
        vac.setApplyUser(instance.getStartUserId());
        vac.setDays(days);
        vac.setReason(reason);
        // activiti 6 才有
        Date startTime = instance.getStartTime();
        vac.setApplyTime(startTime);
        vac.setApplyStatus(instance.isEnded() ? "申请结束" : "等待审批");
        return vac;
    }


}
